package com.wyl.java.thread_.executor_service_;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * ExecutorService是Java提供的一个线程池框架，可以方便地管理和调度多个线程执行任务。
 *
 * ExecutorService提供了多种方法来提交任务，包括execute()、submit()和invokeAll()等。其中，execute()方法用于提交不需要返回值的任务；submit()方法用于提交需要返回值的任务，并返回一个Future对象，可以通过该对象获取任务的执行结果；invokeAll()方法用于提交一组任务，并返回它们的执行结果。
 *
 * ExecutorService还可以管理线程池的大小、线程空闲时间、任务队列等属性，以及提供各种线程池的实现方式。例如，可以使用newFixedThreadPool()创建一个固定大小的线程池，或者使用newCachedThreadPool()创建一个根据需求自动调整线程数的线程池。
 *
 * 使用ExecutorService可以有效地避免频繁地创建和销毁线程带来的性能开销，同时还可以更好地控制线程的数量和资源占用，使程序更具可靠性和稳定性。
 *
 * @author 吴宇亮 on 2023/3/24 15:19
 */
public class ExecutorService01 {

//    是的，一般情况下，在使用完ExecutorService之后，应该调用其shutdown()方法来关闭线程池。这会停止接受新任务，并等待所有已提交的任务完成执行，然后关闭线程池。如果不调用shutdown()方法，则可能会导致程序无法正常退出或资源泄漏等问题。
//
//    可以考虑在应用程序的关闭钩子中添加shutdown()方法调用，以确保在程序终止时关闭线程池。例如，可以使用以下代码：
//
//    ExecutorService executor = Executors.newFixedThreadPool(10);
//Runtime.getRuntime().addShutdownHook(new Thread(() -> {
//        executor.shutdown();
//    }));
//    这将创建一个固定大小为10的线程池，并将shutdown()方法注册为应用程序关闭时的钩子。


    // shutdown方法
    // 调用shutdown方法后，线程池不会立刻停止；而是会立刻停止接收新的任务，然后会等待已提交还未运行的任务执行完毕后，在关闭线程池；但是不会等待正在运行的任务??这个chatGPT回答前后茅盾了，需要验证
    // （换句话说，如果当前有2个任务A、B正在执行，1个任务C正在等待，然后调用shutdown，A执行时间要很长，B和C都很快，当B执行完，C就开始执行，C也执行完了，线程池会直接关闭，不会等待A执行完）
    // 如果需要等待正常运行的线程全部执行完，需要调用awaitTermination，如果超时时间设置成-1，应该可以一直等待
//    executor.shutdown();
//    try {
//        if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
//            executor.shutdownNow();
//        }
//    } catch (InterruptedException ex) {
//        executor.shutdownNow();
//        Thread.currentThread().interrupt();
//    }


}
